import static org.junit.Assert.*;

import java.util.Iterator;

import org.junit.Before;
import org.junit.Test;


public class BribeListTest {
	
	BribeListInterface emptyList;

	@Before
	public void setUp() throws Exception {
		emptyList = new BribeList("Comp132");
	}

	@Test
	public void constructor() {
		String name = emptyList.getClassName();
		assertTrue(name.equals("Comp132"));
		
		Iterator<Briber> iter = emptyList.iterator();
		assertTrue(iter.hasNext() == false);
	}
	
	@Test
	public void firstBriber() {
		Briber first = new Briber("Joe", "Smith", 20);
		emptyList.addBriber(first);

		Iterator<Briber> iter = emptyList.iterator();
		assertTrue(iter.hasNext() == true);
	
		Briber who = iter.next();
		assertTrue(who == first);
	}
	
	@Test
	public void firstBriberUpdated() {
		Briber first = new Briber("Joe", "Smith", 20);
		emptyList.addBriber(first);
		
		BribeListInterface oneEntry = emptyList;
		
		Briber matchesJoeWithAdditionalMoney = new Briber("Joe", "Smith", 30);
		oneEntry.addBriber(matchesJoeWithAdditionalMoney);

		Iterator<Briber> iter = oneEntry.iterator();
		assertTrue(iter.hasNext() == true);
	
		Briber who = iter.next();
		assertTrue(who == first);
		int whoMoney = who.getBribe();
		assertTrue(whoMoney == 20 + 30);
	}
	
	@Test
	public void listInBribeOrder() {
		Briber small = new Briber("ZZ", "ZZ", 10);
		Briber medium = new Briber("MM", "MM", 50);
		Briber large = new Briber("AA", "AA", 200);
		
		BribeListInterface threeEntryList = emptyList;
		
		threeEntryList.addBriber(large);
		threeEntryList.addBriber(medium);
		threeEntryList.addBriber(small);
		
		Iterator<Briber> iter = threeEntryList.iterator();
		
		assertTrue(iter.hasNext() == true);
		Briber who = iter.next();		
		assertTrue(who == small);
		
		assertTrue(iter.hasNext() == true);
		who = iter.next();		
		assertTrue(who == medium);
		
		assertTrue(iter.hasNext() == true);
		who = iter.next();				
		assertTrue(who == large);
	}
	
	@Test
	public void updatedAndOrderChanged() {
		Briber small = new Briber("ZZ", "ZZ", 10);
		Briber medium = new Briber("MM", "MM", 50);
		Briber large = new Briber("AA", "AA", 200);
		
		BribeListInterface threeEntryList = emptyList;
		
		threeEntryList.addBriber(large);
		threeEntryList.addBriber(medium);
		threeEntryList.addBriber(small);
		
		threeEntryList.addBriber(new Briber("MM", "MM", 3000));
		
		Briber gigantic = medium;
		
		Iterator<Briber> iter = threeEntryList.iterator();
		
		assertTrue(iter.hasNext() == true);
		Briber who = iter.next();		
		assertTrue(who == small);
		
		assertTrue(iter.hasNext() == true);
		who = iter.next();		
		assertTrue(who == large);
		
		assertTrue(iter.hasNext() == true);
		who = iter.next();				
		assertTrue(who == gigantic);
	}
	
	@Test
	public void removeHighest() {
		Briber small = new Briber("ZZ", "ZZ", 10);
		Briber medium = new Briber("MM", "MM", 50);
		Briber large = new Briber("AA", "AA", 200);
		
		BribeListInterface threeEntryList = emptyList;
		
		threeEntryList.addBriber(large);
		threeEntryList.addBriber(medium);
		threeEntryList.addBriber(small);
		
		threeEntryList.removeBriber(large);
		
		Iterator<Briber> iter = threeEntryList.iterator();
		
		assertTrue(iter.hasNext() == true);
		Briber who = iter.next();		
		assertTrue(who == small);
		
		assertTrue(iter.hasNext() == true);
		who = iter.next();		
		assertTrue(who == medium);
	}
	
	@Test
	public void removeOtherThantHighest() {
		Briber small = new Briber("ZZ", "ZZ", 10);
		Briber medium = new Briber("MM", "MM", 50);
		Briber large = new Briber("AA", "AA", 200);
		
		BribeListInterface threeEntryList = emptyList;
		
		threeEntryList.addBriber(large);
		threeEntryList.addBriber(medium);
		threeEntryList.addBriber(small);
		
		threeEntryList.removeBriber(medium);
		
		Iterator<Briber> iter = threeEntryList.iterator();
		
		assertTrue(iter.hasNext() == true);
		Briber who = iter.next();		
		assertTrue(who == small);
		
		assertTrue(iter.hasNext() == true);
		who = iter.next();		
		assertTrue(who == large);
	}
}
